﻿using System;
using System.Diagnostics;
using System.Linq;
using System.Xml.Linq;
using Atha.Contracts;
using Atha.Extensions.Strings;
using Atha.Extensions.TestRunTestResults;
using Microsoft.Practices.ServiceLocation;
using Microsoft.Practices.Unity;
using Microsoft.Practices.Unity.Configuration;

namespace Atha.Athax
{
	class Program
	{
		static void Main(string[] args)
		{
			try
			{
				const string inputPathArg = "/IN:";
				const string outputPathArg = "/OUT:";

				string inputPath = null;
				string outputPath = null;

				foreach (var arg in args)
				{
					var uarg = arg.ToUpperInvariant();

					if (uarg.StartsWith(inputPathArg)) inputPath = uarg.Replace(inputPathArg, string.Empty);
					else if (uarg.StartsWith(outputPathArg)) outputPath = uarg.Replace(outputPathArg, string.Empty);
				}

				var unity = new UnityContainer();
				var serviceLocator = new UnityServiceLocator(unity);

				unity.LoadConfiguration();

				ServiceLocator.SetLocatorProvider(() => serviceLocator);

				var fileSystemTestRunContext = unity.Resolve<ITestRunContext<AggregateTestResult>>(
					"FileSystem",
					new ParameterOverride("inputPath", inputPath));

				var testResults = fileSystemTestRunContext.Execute();

				var resultsXml = TransformTestResult(testResults);

				var xml =
					new XDocument(
						new XElement("atha",
							new XAttribute("version", "1.0"),
							new XAttribute("athaxVersion", "1.0"),
							resultsXml));

				Debug.WriteLine(xml.ToString());

				if (!string.IsNullOrEmpty(outputPath))
				{
					try
					{
						xml.Save(outputPath);
#if DEBUG
						Process.Start(outputPath);
#endif
					}
					catch (Exception ex)
					{
						PrintError("Could not save test results. " + ex.Message);
					}
				}

				Exit();
			}
			catch (ArgumentException ex)
			{
				Exit(ex.Message, true);
			}
			catch (Exception ex)
			{
				Exit(ex.Message, false);
			}
		}

		static XElement TransformTestResult(ITestRunTestResult testResult)
		{
			const string t = "true";
			const string f = "false";

			var element = new XElement("test",
				new XAttribute("name", testResult.Name),
				new XAttribute("successful", testResult.Succeeded() ? t : f),
				new XAttribute("error", testResult.IsError() ? t : f),
				new XAttribute("failed", testResult.Failed() ? t : f)
			);

			if (testResult is AggregateTestResult)
			{
				var aggregate = (AggregateTestResult)testResult;

				var childElements = aggregate.Results.Select(r => TransformTestResult(r));

				element.Add(childElements);
			}

			return element;
		}

		static void PrintError(string error)
		{
			Console.WriteLine("Error: {0}".FormatWith(error));
		}

		static void Exit(string error = null, bool printUsage = false)
		{
			if (!string.IsNullOrEmpty(error))
			{
				PrintError(error);
			}

			if (printUsage)
			{
				Console.WriteLine();
				Console.WriteLine("--------------------------------------------------");
				Console.WriteLine(" USAGE:");
				Console.WriteLine("     Input File:");
				Console.WriteLine(@"       AthaX.exe /in:""C:\testscripts\mytest.py""");
				Console.WriteLine("     Input Directory:");
				Console.WriteLine(@"       AthaX.exe /in:""C:\testscripts\""");
				Console.WriteLine("--------------------------------------------------");
				Console.WriteLine();
			}

#if DEBUG
			Console.WriteLine("Press any key to continue.");
			Console.ReadLine();
#endif
		}
	}
}
